package com.sky.common.generate.core;

import java.util.List;
import java.util.Optional;

public class GenerateEntity extends GenerateBase {

    public GenerateEntity(GenerateBase generateBase) {
        super(generateBase.packagePath, generateBase.tableName, generateBase.moduleName, generateBase.className,
                generateBase.fieldList, generateBase.fieldMethod);
    }

    public void execute() {
        StringBuilder builder = new StringBuilder();
        String generatePackage = generatePackage(packagePath + "." + moduleName + ".entity");
//        String generatePackage = generatePackage(packagePath + "." + moduleName );
        String generateClass = generateClass(className);
        String generateAttribute = generateAttribute(fieldList);
        String generateGetSetMethod = generateGetSetMethod(className, fieldList);

        builder.append(generatePackage);
        builder.append(generateImport(generateClass + generateAttribute + generateGetSetMethod));
        builder.append(generateClass);
        builder.append(generateAttribute);
        // builder.append(generateGetSetMethod);

        writeGenerateFile(builder.append("}").toString().getBytes(), getGeneratePath("entity", null));

        Optional<FieldInfo> finfo = fieldList.stream().filter(FieldInfo::isPrimary).findFirst();
        String construction = "";
        if (finfo.isPresent()) {
            FieldInfo field = finfo.get();
            construction = "    private List<" + field.getJavaDataType() + "> ids;\n\n";
            construction += "    public " + className + "Param(" + field.getJavaDataType() + " id) {\n" +
                    "        super.setId(id);\n" +
                    "    }\n";
        }
        // 生成Param类
        String paramClass = "@Getter\n" +
                "@Setter\n" +
                "@ToString\n" +
                "@NoArgsConstructor\npublic class " + className + "Param extends " + className + " {\n " + "\n"
                + construction + "}";
        String paramStr = generatePackage + generateImport(paramClass) + paramClass;
        writeGenerateFile(paramStr.getBytes(), getGeneratePath("entity", "Param"));

        // 生成VO类
        String voClass = "@Getter\n" +
                "@Setter\n" +
                "@ToString\n" +
                "@NoArgsConstructor\npublic class " + className + "VO extends " + className + " {\n " + "\n"
                + "}";
        String voStr = generatePackage + generateImport(voClass) + voClass;
        writeGenerateFile(voStr.getBytes(), getGeneratePath("entity", "VO"));
    }

    /**
     * 生成类
     **/
    public String generateClass(String className) {
        StringBuilder builder = new StringBuilder();
        builder.append("@Getter\n");
        builder.append("@Setter\n");
        builder.append("@ToString\n");
        builder.append("@NoArgsConstructor\n");
        builder.append("public class ").append(className).append(" extends BaseEntity {\n\n");
        return builder.toString();
    }

    /**
     * 生成属性
     **/
    public String generateAttribute(List<FieldInfo> fields) {
        StringBuilder builder = new StringBuilder();
        for (FieldInfo field : fields) {
            if (field.getComment() != null) {
                builder.append("	/** ").append(field.getComment()).append(" **/\n");
            }
            if ("Long".equals(field.getJavaDataType())) {
                builder.append("    @JsonFormat(shape = Shape.STRING)\n");
            }
            builder.append("	private ").append(field.getJavaDataType()).append(" ").append(field.getJavaColumnName())
                    .append(";\n\n");
        }
        return builder.toString();
    }

    /**
     * 生成方法
     **/
    public String generateGetSetMethod(String className, List<FieldInfo> fieldInfos) {
        StringBuilder builder = new StringBuilder();
        String name;
        String type;
        /** 无参构造方法 **/
        builder.append("	public ").append(className).append("() {\n\n	}\n\n");
        for (FieldInfo field : fieldInfos) {
            type = field.getJavaDataType();
            name = field.getJavaColumnName();
            /** Get方法 **/
            if ("Long".equals(type)) {
                builder.append(" @JsonFormat(shape = Shape.STRING)\n");
            }
            builder.append("	public ").append(type).append(" get").append(upper(name)).append("() {\n");
            builder.append("		return ").append(name).append(";\n	}\n\n");

            /** Set方法 **/
            builder.append("	public void").append(" set").append(upper(name)).append("(").append(type).append(" ")
                    .append(name).append(") {\n");
            builder.append("		this.").append(name).append(" = ").append(name).append(";\n	}\n\n");
        }
        return builder.toString();
    }

}
